<!-- <html>

<head>
    <script src="https://d3js.org/d3.v7.min.js"></script>
</head>

<body>
    <svg id="d3Graph" width="800" height="600"></svg>
    <script>
        // Data for nodes and links
        const nodes = [
            { id: 0, name: "A" },
            { id: 1, name: "B" },
            { id: 2, name: "C" },
            { id: 3, name: "D" },
        ];

        const links = [
            { source: 0, target: 1 },
            { source: 0, target: 2 },
            { source: 0, target: 3 },
        ];

        // Create a D3 force simulation
        const simulation = d3
            .forceSimulation(nodes)
            .force("link", d3.forceLink(links).id((d) => d.id))
            .force("charge", d3.forceManyBody().strength(-200))
            .force("center", d3.forceCenter(400, 300));

        // Select the SVG container
        const svg = d3.select("#d3Graph");

        // Create the link elements
        const link = svg
            .selectAll("line")
            .data(links)
            .join("line")
            .attr("stroke", "#999")
            .attr("stroke-opacity", 0.6)
            .attr("stroke-width", 2);

        // Create the node elements
        const node = svg
            .selectAll("circle")
            .data(nodes)
            .join("circle")
            .attr("r", 10)
            .attr("fill", "#f00")
            .attr("cursor", "pointer")
            .on("click", (event, d) => {
                const url = `https://example.com/page${d.name}`;
                window.open(url, "_blank");
            });

        // Create node labels
        const label = svg
            .selectAll("text")
            .data(nodes)
            .join("text")
            .attr("dx", 12)
            .attr("dy", ".35em")
            .text((d) => d.name);

        // Update the positions of the elements on each tick of the simulation
        simulation.on("tick", () => {
            link
                .attr("x1", (d) => d.source.x)
                .attr("y1", (d) => d.source.y)
                .attr("x2", (d) => d.target.x)
                .attr("y2", (d) => d.target.y);

            node.attr("cx", (d) => d.x).attr("cy", (d) => d.y);

            label.attr("x", (d) => d.x).attr("y", (d) => d.y);
        });

    </script>
</body>

</html> -->


<!-- <!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>D3.js Tree Example</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
</head>

<body>
    <svg width="600" height="400"></svg>
    <script>
        // 定义数据
        const data = {
            name: "A",
            children: [
                {
                    name: "B1",
                    children: [
                        { name: "B11" },
                        { name: "B12" }
                    ]
                },
                {
                    name: "C1",
                    children: [
                        { name: "C11" },
                        { name: "C12" },
                        { name: "C13" }
                    ]
                },
                {
                    name: "D1",
                    children: [
                        { name: "C11" },
                        { name: "C12" },
                        { name: "C13" }
                    ]
                }
            ]
        };

        // 定义布局
        const treeLayout = d3.tree()
            .size([400, 200])
            .separation((a, b) => (a.parent == b.parent ? 1 : 2) / a.depth);

        // 转换数据为层次结构数据
        const root = d3.hierarchy(data);

        // 使用布局计算节点位置
        treeLayout(root);

        // 获取节点之间的链接和节点的列表
        const links = root.links();
        const nodes = root.descendants();

        // 创建 SVG 元素
        const svg = d3.select("svg");

        // 创建链接组
        const linkGroup = svg.append("g")
            .attr("fill", "none")
            .attr("stroke", "#999")
            .attr("stroke-opacity", 0.6)
            .attr("stroke-width", 1.5)
            .selectAll("path")
            .data(links)
            .join("path")
            .attr("d", d => `
          M${d.source.y},${d.source.x}
          L${d.target.y},${d.target.x}
        `);

        // 创建节点组
        const nodeGroup = svg.append("g")
            .attr("font-family", "sans-serif")
            .attr("font-size", 10)
            .attr("stroke-linejoin", "round")
            .attr("stroke-width", 3)
            .selectAll("g")
            .data(nodes)
            .join("g")
            .attr("transform", d => `
          translate(${d.y},${d.x})
        `);

        // 创建节点圆圈
        nodeGroup.append("circle")
            .attr("fill", d => d.children ? "#555" : "#999")
            .attr("r", 2.5);

        // 创建节点文字
        nodeGroup.append("text")
            .attr("dy", "0.31em")
            .attr("x", d => d.children ? -6 : 6)
            .attr("text-anchor", d => d.children ? "end" : "start")
            .text(d => d.data.name);

    </script>
</body>

</html> -->


<!-- <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>D3.js 树状图示例</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        .node circle {
            fill: #fff;
            stroke: steelblue;
            stroke-width: 3px;
        }

        .node text {
            font: 12px sans-serif;
        }

        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 2px;
        }
    </style>
</head>

<body>
    <script>
        // 设置SVG的宽度和高度
        var width = 1200,
            height = 900;

        // 创建SVG元素
        var svg = d3.select("body")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

        // 定义树布局
        var tree = d3.tree()
            .size([width, height - 200]);

        // 定义对角线生成器
        var diagonal = d3.linkHorizontal()
            .x(d => d.y)
            .y(d => d.x);

        // 定义根节点数据
        var root = d3.hierarchy({
            name: "根节点",
            children: [
                { name: "节点1", children: [{ name: "节点1.1" }, { name: "节点1.2" }] },
                { name: "节点2", children: [{ name: "节点2.1" }, { name: "节点2.2" }] },
                { name: "节点3", children: [{ name: "节点3.1" }, { name: "节点3.2" }] }
            ]
        });

        // 应用树布局
        tree(root);

        // 绘制连接线
        svg.selectAll(".link")
            .data(root.links())
            .enter()
            .append("path")
            .attr("class", "link")
            .attr("d", diagonal);

        // 绘制节点
        var nodes = svg.selectAll(".node")
            .data(root.descendants())
            .enter()
            .append("g")
            .attr("class", "node")
            .attr("transform", d => `translate(${d.y},${d.x})`);

        // 添加圆圈
        nodes.append("circle")
            .attr("r", 10);

        // 添加文字标签
        nodes.append("text")
            .attr("dx", d => d.children ? -15 : 15)
            .attr("dy", 3)
            .style("text-anchor", d => d.children ? "end" : "start")
            .text(d => d.data.name);
    </script>
</body>

</html> -->

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Vertical Tree Diagram</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
</head>

<body>
    <script>
        // Prepare the data
        const data = {
            name: 'Root',
            children: [
                {
                    name: 'A',
                    children: [
                        { name: 'A1' },
                        { name: 'A2' }
                    ]
                },
                {
                    name: 'B',
                    children: [
                        { name: 'B1' },
                        { name: 'B2' }
                    ]
                }
            ]
        };

        // Set up the environment
        const width = 800;
        const height = 600;
        const margin = { top: 50, right: 50, bottom: 50, left: 50 };

        const svg = d3.select('body')
            .append('svg')
            .attr('width', width)
            .attr('height', height);

        // Create the tree layout
        const treeLayout = d3.tree()
            .size([width - margin.left - margin.right, height - margin.top - margin.bottom]);

        const hierarchyData = d3.hierarchy(data);

        const treeData = treeLayout(hierarchyData);

        // Draw the nodes
        const nodes = svg.selectAll('.node')
            .data(treeData.descendants())
            .enter()
            .append('g')
            .attr('class', 'node')
            .attr('transform', d => `translate(${d.x + margin.left}, ${d.y + margin.top})`);

        nodes.append('circle')
            .attr('r', 10);

        nodes.append('text')
            .text(d => d.data.name)
            .attr('dy', '.35em')
            .attr('y', d => (d.children ? -20 : 20))
            .style('text-anchor', 'middle');

        // Draw the links
        const links = svg.selectAll('.link')
            .data(treeData.links())
            .enter()
            .append('path')
            .attr('class', 'link')
            .attr('d', d3.linkVertical()
                .x(d => d.x + margin.left)
                .y(d => d.y + margin.top))
            .style('stroke', '#ccc')
            .style('stroke-width', 2)
            .style('fill', 'none');

    </script>
</body>

</html>